package com.maowu.pooling.test;

import java.net.SocketException;

import com.maowu.pooling.ConnectionDamagedException;
import com.maowu.pooling.ConnectionFactory;
import com.maowu.pooling.FailedToConnectException;

public class MyConnectionStubFactory implements ConnectionFactory
{
    private long createRequiredTime = 0;
    private long connectRequiredTime = 100;
    private long businessRequiredTime = 10;
    private boolean returnNull = false;
    private boolean failedToConnect = false;
    
    private int counter = 0;
    
    public Object createConnection(long connectTimeout)
                    throws FailedToConnectException
    {
        
        if (returnNull)
        {
            return null;
        }
        MyConnectionStub conn = new MyConnectionStub();
        conn.setConnectRequiredTime(connectRequiredTime);
        conn.setConnectRequiredTime(connectRequiredTime);
        conn.setCreateRequiredTime(createRequiredTime);
        counter ++;
        try
        {
            Thread.sleep(createRequiredTime);
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        try
        {
            touchConnection(conn, connectTimeout);
        }
        catch (ConnectionDamagedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        

        return conn;
    }

    public void destroyConnection(Object conn)
    {
        ((MyConnectionStub)conn).setDestroyed(true);

    }

    public void touchConnection(Object conn, long connectTimeout)
                    throws FailedToConnectException, ConnectionDamagedException
    {
        MyConnectionStub c = (MyConnectionStub)conn;
        if (c.isDamaged())
        {
            throw new ConnectionDamagedException();
        }
        if (c.isConnected())
        {
            return;
        }
        
        if (c.isFailedToConnect() || failedToConnect)
        {
            throw new FailedToConnectException(new SocketException());
        }
        try
        {
            Thread.sleep(Math.min(connectTimeout, connectRequiredTime));
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if (connectTimeout > connectRequiredTime)
        {
            ((MyConnectionStub)conn).setConnected(true);
        }
        else 
        {
            throw new FailedToConnectException();
        }
        

    }

    public long getBusinessRequiredTime()
    {
        return businessRequiredTime;
    }

    public void setBusinessRequiredTime(long businessRequiredTime)
    {
        this.businessRequiredTime = businessRequiredTime;
    }

    public long getConnectRequiredTime()
    {
        return connectRequiredTime;
    }

    public void setConnectRequiredTime(long connectRequiredTime)
    {
        this.connectRequiredTime = connectRequiredTime;
    }

    public long getCreateRequiredTime()
    {
        return createRequiredTime;
    }

    public void setCreateRequiredTime(long createRequiredTime)
    {
        this.createRequiredTime = createRequiredTime;
    }

    public int getCounter()
    {
        return counter;
    }

    public void setCounter(int counter)
    {
        this.counter = counter;
    }

    public boolean isReturnNull()
    {
        return returnNull;
    }

    public void setReturnNull(boolean returnNull)
    {
        this.returnNull = returnNull;
    }

    public boolean isFailedToConnect()
    {
        return failedToConnect;
    }

    public void setFailedToConnect(boolean failedToConnect)
    {
        this.failedToConnect = failedToConnect;
    }

}
